package com.project.frba.bifront.client.view.descriptors;

import java.util.HashMap;
import java.util.Map;

import com.google.gwt.core.client.GWT;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.Composite;
import com.gwtext.client.core.EventObject;
import com.gwtext.client.data.FieldDef;
import com.gwtext.client.data.Record;
import com.gwtext.client.data.RecordDef;
import com.gwtext.client.data.Store;
import com.gwtext.client.data.StringFieldDef;
import com.gwtext.client.widgets.Button;
import com.gwtext.client.widgets.Window;
import com.gwtext.client.widgets.event.ButtonListenerAdapter;
import com.gwtext.client.widgets.grid.ColumnConfig;
import com.gwtext.client.widgets.grid.ColumnModel;
import com.gwtext.client.widgets.grid.GridPanel;
import com.gwtext.client.widgets.layout.FitLayout;
import com.project.frba.bifront.client.BiPanel;
import com.project.frba.bifront.client.model.FrontDescriptor;
import com.project.frba.bifront.client.rpc.ETLServices;
import com.project.frba.bifront.client.rpc.ETLServicesAsync;
import com.project.frba.bifront.client.rpc.FrontGeneralServices;
import com.project.frba.bifront.client.rpc.FrontGeneralServicesAsync;
import com.project.frba.bifront.client.view.MessageWindow;
import com.project.frba.bifront.client.view.users.ListGridListener;

public class DescriptorList extends Composite {

	private Window mainWindow = new Window("Descriptores");
	
	private BiPanel parent = null;
	
	private Map<String, FrontDescriptor> descriptors = new HashMap<String, FrontDescriptor>();
	
	private GridPanel gridPanel = new GridPanel();
	
	private Button btExecuteAll = new Button("Ejecutar todos");
	
	private Button btExecute = new Button("Ejecutar");
	
	private Button btAdd = new Button("Agregar descriptor");
	
	private Button btRemove = new Button("Eliminar");
	
	private String selectedDescriptor = null;
	
	private RecordDef recordDef = null;
	
	public DescriptorList(BiPanel biPanel) {
		this.parent = biPanel;
		this.descriptors = parent.getDescriptors();
		
		FieldDef[] fieldDef = new FieldDef[] {
				new StringFieldDef("name"),
				new StringFieldDef("label")
				};
		recordDef = new RecordDef(fieldDef);

		ColumnConfig[] columns = new ColumnConfig[] {
				new ColumnConfig("Nombre del descriptor", "name", 150, true, null ),
				new ColumnConfig("Metrica", "label", 250, true, null)
			};
		
		ColumnModel columnModel = new ColumnModel(columns);
		
		Store store = new Store(recordDef);
		
		gridPanel.setStore(store);
		gridPanel.setColumnModel(columnModel);
		gridPanel.setLayout(new FitLayout());
		gridPanel.setFrame(false);  
		gridPanel.setStripeRows(true);  
		gridPanel.setHeight(250);  
		gridPanel.setWidth(400);
		
		loadListing();
		loadActions();
		mainWindow.add(gridPanel);
		mainWindow.setWidth(420);
		mainWindow.setLayout(new FitLayout());
		mainWindow.setButtons(new Button[]{btExecuteAll, btExecute, btAdd, btRemove});
		initWidget(mainWindow);
		mainWindow.show();
	}
	
	private void loadActions(){
		final DescriptorList me = this;
		
		btExecute.addListener(new ButtonListenerAdapter() {
			public void onClick(Button button, EventObject e) {
				ETLServicesAsync etlServices = (ETLServicesAsync)GWT.create(ETLServices.class);
				AsyncCallback<Boolean> callback = new AsyncCallback<Boolean>() {
					public void onSuccess(Boolean result) {
						new MessageWindow("Este proceso puede demorar unos minutos, durante ese tiempo puede que no se noten cambios en la información.");
					}
					
					public void onFailure(Throwable caught) {
						new MessageWindow("Ha ocurrido un error, intente mas tarde.");
					}
				};
				etlServices.executeETLService(selectedDescriptor, callback);
				
			}
		});
		
		btExecuteAll.addListener(new ButtonListenerAdapter() {
			public void onClick(Button button, EventObject e) {
				ETLServicesAsync etlServices = (ETLServicesAsync)GWT.create(ETLServices.class);
				AsyncCallback<Boolean> callback = new AsyncCallback<Boolean>() {
					public void onSuccess(Boolean result) {
						new MessageWindow("Este proceso puede demorar unos minutos, durante ese tiempo puede que no se noten cambios en la información.");
					}
					
					public void onFailure(Throwable caught) {
						new MessageWindow("Ha ocurrido un error, intente mas tarde.");
					}
				};
				etlServices.executeAllETLServices(callback);
				
			}
		});
		
		btAdd.addListener(new ButtonListenerAdapter() {
			public void onClick(Button button, EventObject e) {
				new UploadDescriptorForm(me);
				
			}
		});
		
		btRemove.addListener(new ButtonListenerAdapter() {
			public void onClick(Button button, EventObject e) {
				FrontGeneralServicesAsync frontGeneralServices = (FrontGeneralServicesAsync)GWT.create(FrontGeneralServices.class);
				AsyncCallback<Boolean> callback = new AsyncCallback<Boolean>(){
					public void onFailure(Throwable caught) {
						new MessageWindow("Ha ocurrido un error al intentar borrar el descriptor.");
						
					}
					public void onSuccess(Boolean result) {
						if(result.equals(true)){
							new MessageWindow("Se ha borrado satisfactoriamente el descriptor.", true);
							parent.loadDescriptors();
							Record record = gridPanel.getSelectionModel().getSelected();
							Store store = gridPanel.getStore();
							store.remove(record);
							store.commitChanges();
							
						} else {
							new MessageWindow("No se encontro el archivo");
						}
					}
				};
				
				frontGeneralServices.removeDescriptor(selectedDescriptor, callback);
			}
		});
		
		gridPanel.addGridListener(new ListGridListener() {
			public void onDblClick(EventObject e) {
				Record record = gridPanel.getSelectionModel().getSelected();
				selectedDescriptor = record.getAsString("name");
				new DescriptorForm(descriptors.get(selectedDescriptor) , me);
			}
			
			public void onClick(EventObject e) {
				Record record = gridPanel.getSelectionModel().getSelected();
				selectedDescriptor = record.getAsString("name");
			}
		});
	}
	
	private void loadListing() {
		Store store = gridPanel.getStore();
		store.removeAll();
		for (String descriptorName : descriptors.keySet()) {
			FrontDescriptor descriptor = descriptors.get(descriptorName);
			store.add(recordDef.createRecord(descriptor.getDescriptorName(), new Object[]{
					descriptor.getDescriptorName(),
					descriptor.getLabel()
					}));
			store.commitChanges();
		}
	}
	
	public void reload(){
		parent.loadDescriptors();
		descriptors = parent.getDescriptors();
		loadListing();
	}
	
	
}
